package fr.ups.jim.isi.tp3 ;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File ;
import java.util.Vector;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog ;
import javax.swing.JFrame ;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;


/**
 * @author Ji MA (Universite Paris Sud (ji.ma@u-psud.fr)
 *
 */
public class MyFileSelector extends JDialog {

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	// self defined widgets
	private JComboBox parent_dirs;
	private JList files_list;
	private JScrollPane files_scroller;
	private JButton btn_cancel;
	private JButton btn_open;
	private JPanel btns_panel;	// containter for "button_cancel" and "button_panel"
	
	private String directory = null ;
    private String file = null ;
    
    // this ActionListener responds to the selection of one item in the combo box
    private ActionListener parent_dirs_listener = new ActionListener() {
    	public void actionPerformed(ActionEvent e){
    		// Attention, absoulte file path of current directory is splited into 
    		// a number of Strings by File.sperator, and these Strings are listed 
    		// in an reverse order in the combo box
    		int index = parent_dirs.getSelectedIndex();
    		if(index < 1) {
    			// If index is 0, it means the chooser select current directory, keep two lists
    			// unchanged is reasonable. 
    			return ;
    		}
    		else{
    			// construct the correct absolute file path for the selected item
    			String abs_path = "";
    			for (int i = parent_dirs.getItemCount()-2; i >= index ; i-- ){
    				abs_path = abs_path + parent_dirs.getItemAt(i) + File.separator;
    			}
    			show(abs_path);
    		}
    	}
    };
    
    // this ActionListener responds to two buttons "btn_cancel" and "btn_open"
  
    // btn_listener is responsible for responding action from "Cancel" or "Open" button
    private ActionListener btn_listener = new ActionListener() {
    	public void actionPerformed(ActionEvent e) {
    		JButton btn_source = (JButton)e.getSource();
    		if (btn_source == btn_cancel)
    			dispose();
    		else if (btn_source == btn_open) {
    			file = (String)files_list.getSelectedValue();
    			if(!show(getFilePath())) {
    				JOptionPane.showMessageDialog(null, 
    						"Please choose a valide DIRECTORY!", 
    						"Alert", 
    						JOptionPane.ERROR_MESSAGE);
    			}
    		}
    	}
    };
    
    // this ListSelectionListener responds to the List Selection in "files_list"
    private ListSelectionListener files_list_listener = new ListSelectionListener(){
    	public void valueChanged(ListSelectionEvent e){
    		if (e.getValueIsAdjusting()) return ;
    		btn_open.setEnabled((files_list.getSelectedIndex()!=-1));
    	}
    };
    
    // this MouseAdapter responds to the double click on an item in the "files_list"
    private MouseAdapter files_list_mouse_listener = new MouseAdapter() {
		  public void mouseClicked(MouseEvent e){
			 if (e.getClickCount()==2) btn_open.doClick() ;
		  }
	   } ;
    
    public MyFileSelector(String title, String lbl_cancel, String lbl_ok) {
	   super((JFrame)null, title, true /* modal */) ;
	   
	   // set attributes of Container
	   setSize(300,400);
	   setLocation(300, 200);
	   setLayout(new BorderLayout());
	   
	   // initialization for private widgets	   
	   parent_dirs = new JComboBox();
	   parent_dirs.addActionListener(parent_dirs_listener);
	   
	   files_list = new JList();
	   files_list.addListSelectionListener(files_list_listener);
	   files_list.addMouseListener(files_list_mouse_listener);
	   files_list.setVisibleRowCount(10);
	   files_scroller = new JScrollPane(files_list);
	   
	   btns_panel = new JPanel();
	   btn_cancel = new JButton("Cancel");
	   btn_cancel.addActionListener(btn_listener);
	   btn_open = new JButton("Open");
	   btn_open.addActionListener(btn_listener);
	   
	   // Control the position of widgets
	   add(parent_dirs, BorderLayout.NORTH);
	   add(files_scroller, BorderLayout.CENTER);
	   
	   btns_panel.add(btn_cancel);
	   btns_panel.add(btn_open);
	   add(btns_panel, BorderLayout.SOUTH);
	   
	   show(System.getProperty("user.dir")) ;

	   setVisible(true) ;
    }

    
    Boolean show(String path) {
	   File dir = new File(path) ;
	   if (!dir.exists() || !dir.isDirectory()) 
		   return false ;

	   directory = dir.getAbsolutePath() ;
	   //System.out.println(directory) ;
	   file = null ;
	   btn_open.setEnabled(false);
	   
	   parent_dirs.removeAllItems();
	   files_list.setListData(new Vector<String>());
	   
	   // update the files listed in the files_list
	   String[] files = dir.list();
	   if (files!=null) {
		   for(int i=0; i<files.length; i++) {
			   File f = new File(path, files[i]);
			   if (f.isDirectory()) files[i] = files[i]+File.separator ;
		   }
		   files_list.setListData(files);
	   }
	   
	   // update the combo box which shows the list of parent directories
	   parent_dirs.insertItemAt(File.separator, 0);
	   String[] dirs = path.split(Pattern.quote(File.separator)) ;
	   for (String p : dirs) {
		  if (p.equals("")) continue ;
		  //System.out.format("  parentdir: %s\n",p) ;
		  if (!p.equals("\\"))
		  parent_dirs.insertItemAt(p, 0);
	   }
	   parent_dirs.setSelectedIndex(0);
	   
	   return true ;
    }

    // if choosen path is not a directory, return null
    // if yes, return its absolute path
    public String getFilePath() {
	   if (directory==null || file==null) return null ;
	   return directory+File.separator+file ;
    }
	
    static public void main(String args[]) {
	   MyFileSelector fs = new MyFileSelector("File open...","Cancel","Open") ;
	   System.exit(1) ;
    }

}
